package com.java.Stream;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class EndAPI {
    public static void main(String[] args) {
        // forEach：遍历
        Stream.of(1, 2, 3, 4, 5, 6, 7)
                .forEach(item -> System.out.print(item + " ")); // 1 2 3 4 5 6 7
        System.out.println();
        
        // toArray：流转数组
        Object[] array = Stream.of(1, 2, 3, 4, 5, 6, 7)
                .toArray();
        System.out.println(array.length); // 7
        
        // collect(Collectors.toXxx())：流转集合
        List<Integer> list = Stream.of(1, 2, 3, 4, 5, 6, 7)
                .collect(Collectors.toList());
        System.out.println(list); // [1, 2, 3, 4, 5, 6, 7]
        Set<Integer> set = Stream.of(1, 1, 2, 2, 3, 4)
                .collect(Collectors.toSet());
        System.out.println(set); // [1, 2, 3, 4]
        Map<Integer, String> map = Stream.of(1, 2, 3, 4, 5, 6, 7)
                .collect(Collectors.toMap(item -> item, item -> "" + item)); // 需要保证键的唯一性，若不唯一则抛出异常IllegalStateException
        System.out.println(map); // {1=1, 2=2, 3=3, 4=4, 5=5, 6=6, 7=7}
        
        // collect(Collectors.groupingBy(分组元素))：分组。返回类型为Map<分组元素, 同组数据List>
        System.out.println(Stream.of(1, 1, 2, 2, 2, 3, 4)
                .collect(Collectors.groupingBy(item -> item))); // {1=[1, 1], 2=[2, 2, 2], 3=[3], 4=[4]}
        
        // collect(Collectors.计算())：对集合内数据进行计算
        System.out.println(Stream.of(1, 2, 3, 4, 5, 6, 7) // counting元素总数
                .collect(Collectors.counting())); // 7
        System.out.println(Stream.of(1, 2, 3, 4, 5, 6, 7) // maxBy排序后取最末元素
                .collect(Collectors.maxBy(((o1, o2) -> o2 - o1)))); // Optional[1]
        System.out.println(Stream.of(1, 2, 3, 4, 5, 6, 7) // minBy排序后取最初元素
                .collect(Collectors.minBy(((o1, o2) -> o2 - o1)))); // Optional[7]
        System.out.println(Stream.of(1, 2, 3, 4, 5, 6, 7) // summingXxx求和
                .collect(Collectors.summingInt(item -> item))); // 28
        System.out.println(Stream.of(1, 2, 3, 4, 5, 6, 7) // averagingXxx平均值
                .collect(Collectors.averagingInt(item -> item))); // 4.0
        System.out.println(Stream.of(1, 2, 3, 4, 5, 6, 7) // summarizingXxx不管需不需要，一次性统计各种值，与mapToXxx的区别是mapToXxx需要时才统计
                .collect(Collectors.summarizingInt(item -> item))); // IntSummaryStatistics{count=7, sum=28, min=1, average=4.000000, max=7}
        
        // findFirst：获取第一个元素
        System.out.println(Stream.of(1, 2, 3, 4, 5, 6, 7)
                .findFirst()); // Optional[1]
        
        // findAny：获取串行流第一个元素，并行流任意一个元素
        System.out.println(Stream.of(1, 2, 3, 4, 5, 6, 7)
                .findAny()); // Optional[1]
        System.out.println(Arrays.asList(1, 2, 3, 4, 5, 6, 7).parallelStream()
                .findAny()); // Optional[5]
        
        // count：统计元素总数
        System.out.println(Stream.of(1, 2, 3, 4, 5, 6, 7)
                .count()); // 7
        
        // max：排序后取最末元素
        System.out.println(Stream.of(1, 2, 3, 4, 5, 6, 7)
                .max((o1, o2) -> o2 - o1)); // Optional[1]
        
        // min：排序后取最初元素
        System.out.println(Stream.of(1, 2, 3, 4, 5, 6, 7)
                .min((o1, o2) -> o2 - o1)); // Optional[7]
        
        // reduce：规约
        System.out.println(Stream.of(1, 2, 3, 4, 5, 6, 7)
                .reduce(10, (oldVal, newVal) -> {
                    System.out.println(oldVal); // 10 11 13 16 20 25 31
                    System.out.println(newVal); // 1  2  3  4  5  6  7
                    return oldVal + newVal;
                })); // 38
        System.out.println(Stream.of(1, 2, 3, 4, 5, 6, 7)
                .reduce((oldVal, newVal) -> {
                    System.out.println(oldVal); // 1 3 6 10 15 21
                    System.out.println(newVal); // 2 3 4 5  6  7
                    return oldVal + newVal;
                })); // Optional[28]
        
        // allMatch：所有元素满足条件则返回true
        System.out.println(Stream.of(1, 2, 3, 4, 5, 6, 7)
                .allMatch(item -> item > 0)); // true
        System.out.println(Stream.of(1, 2, 3, 4, 5, 6, 7)
                .allMatch(item -> item > 1)); // false
        
        // anyMatch：任意一个元素满足条件则返回true
        System.out.println(Stream.of(1, 2, 3, 4, 5, 6, 7)
                .anyMatch(item -> item > 6)); // true
        System.out.println(Stream.of(1, 2, 3, 4, 5, 6, 7)
                .anyMatch(item -> item > 7)); // false
        
        // noneMatch：都不满足条件则返回true
        System.out.println(Stream.of(1, 2, 3, 4, 5, 6, 7)
                .noneMatch(item -> item > 6)); // false
        System.out.println(Stream.of(1, 2, 3, 4, 5, 6, 7)
                .noneMatch(item -> item > 7)); // true
    }
}
